#![allow(non_camel_case_types, non_snake_case)]
use crate::co;
use crate::decl::*;
use crate::guard::*;
use crate::kernel::ffi_types::*;
use crate::ole::privs::*;
use crate::prelude::*;
use crate::vt::*;
#[repr(C)]
pub struct IPinVT {
pub IUnknownVT: IUnknownVT,
pub Connect: fn(COMPTR, COMPTR, PCVOID) -> HRES,
pub ReceiveConnection: fn(COMPTR, COMPTR, PCVOID) -> HRES,
pub Disconnect: fn(COMPTR) -> HRES,
pub ConnectedTo: fn(COMPTR, *mut COMPTR) -> HRES,
pub ConnectionMediaType: fn(COMPTR, PVOID) -> HRES,
pub QueryPinInfo: fn(COMPTR, PVOID) -> HRES,
pub QueryDirection: fn(COMPTR, PVOID) -> HRES,
pub QueryId: fn(COMPTR, *mut PSTR) -> HRES,
pub QueryAccept: fn(COMPTR, PCVOID) -> HRES,
pub EnumMediaTypes: fn(COMPTR, *mut COMPTR) -> HRES,
pub QueryInternalConnections: fn(COMPTR, *mut COMPTR, *mut u32) -> HRES,
pub EndOfStream: fn(COMPTR) -> HRES,
pub BeginFlush: fn(COMPTR) -> HRES,
pub EndFlush: fn(COMPTR) -> HRES,
pub NewSegment: fn(COMPTR, i64, i64, f64) -> HRES,
}
com_interface! { IPin: "56a86891-0ad4-11ce-b03a-0020af0ba770";
}
impl dshow_IPin for IPin {}
pub trait dshow_IPin: ole_IUnknown {
fn_com_noparm! { BeginFlush: IPinVT;
}
fn Connect(&self,
receive_pin: &impl dshow_IPin,
mt: Option<&AM_MEDIA_TYPE>,
) -> HrResult<()>
{
ok_to_hrresult(
unsafe {
(vt::<IPinVT>(self).Connect)(
self.ptr(),
receive_pin.ptr(),
mt.map_or(std::ptr::null(), |amt| amt as *const _ as _),
)
},
)
}
fn_com_interface_get! { ConnectedTo: IPinVT, IPin;
}
fn ConnectionMediaType(&self, amt: &mut AM_MEDIA_TYPE) -> HrResult<()> {
ok_to_hrresult(
unsafe {
(vt::<IPinVT>(self).ConnectionMediaType)(
self.ptr(),
amt as *mut _ as _,
)
},
)
}
fn_com_noparm! { Disconnect: IPinVT;
}
fn_com_noparm! { EndFlush: IPinVT;
}
fn_com_noparm! { EndOfStream: IPinVT;
}
fn_com_interface_get! { EnumMediaTypes: IPinVT, IEnumMediaTypes;
}
fn NewSegment(&self, start: i64, stop: i64, rate: f64) -> HrResult<()> {
ok_to_hrresult(
unsafe {
(vt::<IPinVT>(self).NewSegment)(self.ptr(), start, stop, rate)
},
)
}
#[must_use]
fn QueryAccept(&self, amt: &AM_MEDIA_TYPE) -> HrResult<bool> {
okfalse_to_hrresult(
unsafe {
(vt::<IPinVT>(self).QueryAccept)(self.ptr(), amt as *const _ as _)
},
)
}
#[must_use]
fn QueryDirection(&self) -> HrResult<co::PIN_DIRECTION> {
let mut pin_dir = co::PIN_DIRECTION::INPUT;
ok_to_hrresult(
unsafe {
(vt::<IPinVT>(self).QueryDirection)(
self.ptr(),
&mut pin_dir as *mut _ as _,
)
},
).map(|_| pin_dir)
}
#[must_use]
fn QueryId(&self) -> HrResult<String> {
let mut pstr = std::ptr::null_mut::<u16>();
ok_to_hrresult(
unsafe { (vt::<IPinVT>(self).QueryId)(self.ptr(), &mut pstr) },
).map(|_| {
let name = unsafe { WString::from_wchars_nullt(pstr) };
let _ = unsafe { CoTaskMemFreeGuard::new(pstr as _, 0) };
name.to_string()
})
}
#[must_use]
fn QueryInternalConnections(&self) -> HrResult<Vec<IPin>> {
let mut count = u32::default();
if let Err(e) = ok_to_hrresult(
unsafe {
(vt::<IPinVT>(self).QueryInternalConnections)(
self.ptr(),
std::ptr::null_mut(),
&mut count as *mut _ as _,
)
},
) {
return Err(e);
}
let mut queried = vec![unsafe { IPin::null() }];
ok_to_hrresult(
unsafe {
(vt::<IPinVT>(self).QueryInternalConnections)(
self.ptr(),
queried.as_mut_ptr() as _,
&mut count as *mut _ as _,
)
},
).map(|_| queried)
}
fn QueryPinInfo(&self, info: &mut PIN_INFO) -> HrResult<()> {
ok_to_hrresult(
unsafe {
(vt::<IPinVT>(self).QueryPinInfo)(self.ptr(), info as *mut _ as _)
},
)
}
fn ReceiveConnection(&self,
connector: &impl dshow_IPin,
mt: &AM_MEDIA_TYPE,
) -> HrResult<()>
{
ok_to_hrresult(
unsafe {
(vt::<IPinVT>(self).ReceiveConnection)(
self.ptr(),
connector.ptr(),
mt as *const _ as _,
)
},
)
}
}